// Package dlog 用于整合slog的日志框架
package dlog

import (
	"fmt"
	"log/slog"
	"os"
)

// Level 级别设置
type Level int

const (
	LevelDebug Level = -4
	LevelInfo  Level = 0
	LevelWarn  Level = 4
	LevelError Level = 8
)

// Logging domain.
var l *slog.Logger

// 初始化
func init() {
	SetDefaultLogger()
}

// GetLogger 获取logger实例，该实例默认是 SetDefaultLogger 初始化的。
//
// 可以通过 SetFileJsonLogger 或者 SetFileTextLogger 来修改实例的默认属性
func GetLogger() *slog.Logger {
	return l
}

// SetDefautJsonLogger 默认的日志配置，使用官方的slog，输出是标准输出，格式json
//
// 参数：
//
//	addSource：是否记录日志位置
//	level：日志级别
//	replaceAttr：日志字段替换函数
func SetDefautJsonLogger(addSource bool, level slog.Leveler, replaceAttr func(groups []string, a slog.Attr) slog.Attr) *slog.Logger {
	l = slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
		AddSource:   addSource, // 记录日志位置
		Level:       level,     // 设置日志级别
		ReplaceAttr: replaceAttr,
	}))
	slog.SetDefault(l)

	return l
}

// SetDefaultTextLogger 默认的日志配置，使用官方的slog，输出是标准输出，格式文本
//
// 参数：
//
//	addSource：是否记录日志位置
//	level：日志级别
//	replaceAttr：日志字段替换函数
func SetDefaultTextLogger(addSource bool, level slog.Leveler, replaceAttr func(groups []string, a slog.Attr) slog.Attr) *slog.Logger {
	l = slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
		AddSource:   addSource, // 记录日志位置
		Level:       level,     // 设置日志级别
		ReplaceAttr: replaceAttr,
	}))
	slog.SetDefault(l)

	return l
}

// SetDefaultTextLogger 初始化的日志配置，使用官方的slog，输出是标准输出，格式json
//
// 参数：
//
//	addSource：是否记录日志位置
//	level：日志级别
//	replaceAttr：日志字段替换函数
func SetDefaultLogger() *slog.Logger {
	l = slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
		AddSource:   true,            // 记录日志位置
		Level:       slog.LevelDebug, // 设置日志级别
		ReplaceAttr: nil,
	}))
	slog.SetDefault(l)

	return l
}

/*
FuncSetLogTime 传入handler中，将日志的time字段修改为自定义的时间字符串

参数：

	t:自定义时间字符串
*/
func FuncSetLogTime(t string) func(groups []string, a slog.Attr) slog.Attr {
	return func(groups []string, a slog.Attr) slog.Attr {
		if a.Key == "time" {
			a.Value = slog.StringValue(t)
			return a
		}
		return a
	}
}

// SetFileJsonLogger 设置日志实例，使用官方的slog，输出是文件输出，格式json
//
// 参数：
//
//	path:输出文件路径
//	addSource：是否记录日志位置
//	level：日志级别
//	replaceAttr：日志字段替换函数
func SetFileJsonLogger(path string, addSource bool, level slog.Leveler, replaceAttr func(groups []string, a slog.Attr) slog.Attr) *slog.Logger {
	file, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
	if err != nil {
		fmt.Println(err.Error())
		panic(any(err.Error()))
	}
	l = slog.New(slog.NewJSONHandler(file, &slog.HandlerOptions{
		AddSource:   addSource, // 记录日志位置
		Level:       level,     // 设置日志级别
		ReplaceAttr: replaceAttr,
	}))
	slog.SetDefault(l)

	return l
}

// SetFileTextLogger 设置日志实例，使用官方的slog，输出是文件输出，格式文本
//
// 参数：
//
//	path:输出文件路径
//	addSource：是否记录日志位置
//	level：日志级别
//	replaceAttr：日志字段替换函数
func SetFileTextLogger(path string, addSource bool, level slog.Leveler, replaceAttr func(groups []string, a slog.Attr) slog.Attr) *slog.Logger {
	file, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
	if err != nil {
		fmt.Println(err.Error())
		panic(any(err.Error()))
	}
	l = slog.New(slog.NewTextHandler(file, &slog.HandlerOptions{
		AddSource:   addSource, // 记录日志位置
		Level:       level,     // 设置日志级别
		ReplaceAttr: replaceAttr,
	}))
	slog.SetDefault(l)

	return l
}
